package com.kl.controller;


import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.kl.domain.*;
import com.kl.dto.Coupon;
import com.kl.em.ConstantEnum;
import com.kl.em.Result;
import com.kl.entity.Detailed;
import com.kl.feign.*;
import com.kl.service.ICouponService;
import com.kl.service.IDetailedService;
import com.kl.service.IOrderService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;

import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author author
 * @since 2021-10-30
 */
@RestController
@RequestMapping("/order")
@Api(value = "下单管理接口")
public class OrderController {
    @Autowired
    private ICouponService couponService;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private IDetailedService detailedService;
    @Autowired
    private FreightServiceFeign freightServiceFeign;
    @Autowired
    private OrderServcieFeign orderServcieFeign;
    @Autowired
    private LineServcieFeign lineServcieFeign;
    @Autowired
    private TradeController tradeController;

    @Autowired
    private ThreeSelectFeign threeSelectFeign;
    @ApiOperation(value = "增加物价详情")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderDTO", value = "实体类", required = false, paramType = "body"),
            @ApiImplicitParam(name = "token", value = "token", required = false, paramType = "query"),
            @ApiImplicitParam(name = "sid", value = "优惠券id", required = false, paramType = "query")
    })
    @PostMapping("/cd")
    public Result add(@RequestBody List<OrderDTO>  orderDTO,@RequestParam String token,@RequestParam Long sid) throws AlipayApiException {
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        String login_user = (String)redisTemplate.boundValueOps(token).get();
        if( login_user==null){
            return Result.build(ConstantEnum.NOLOGIN);
        }

        UserDTO userDTO = JSONObject.parseObject(login_user,UserDTO.class);
        //todo 获取用户id 到订单表中signreceipt
        Integer pri = 0;
        for (int i = 0; i < orderDTO.size(); i++) {
            Result price = freightServiceFeign.getPrice(1, orderDTO.get(i).getCargoVolume().intValue(), orderDTO.get(i).getCargoWeight().intValue());
            if(price.getCode()==1007){
                return Result.build(ConstantEnum.FaillBack).setResult("价格");
            }
            Integer result =(Integer) price.getResult();
            //评估金额 预估金额
            pri+=result;
            BigDecimal bigDecimal = new BigDecimal(result);
            //调用路线接口
            System.out.println(orderDTO.get(i).getSenderAddress());
            System.out.println(orderDTO.get(i).getConsigneeAddress());
            Result<LineDTO> result1 = lineServcieFeign.selectByBoth(orderDTO.get(i).getSenderAddress(), orderDTO.get(i).getConsigneeAddress());
            if(result1.getCode().equals(1007)){
                 System.out.println(result1.getCode());
                 System.out.println(result1.getMessage());
                 System.out.println(result1.getResult()+":list");
                 return Result.build(ConstantEnum.FaillBack).setResult("路线");
            }
            //test手动生成路线对象测试
            LineDTO lineDTO = new LineDTO();
            lineDTO.setId(2L).setStatrAddress("北京").setEndAddress("天津").setSiteCount(2).setLineLength(141L).setLineTime(1L).setLineCity("[\"北京\",\"天津市\"]");
            //LineDTO result3 = lineDTO;
            LineDTO result3 = result1.getResult();
            System.out.println(result3);
            // todo 路线计算的价格
            Integer siteCount = result3.getSiteCount();
            //根据路线计算价钱
            int li = siteCount*5;
            pri+=li;
        }

        //获取当前站点
        for (int i = 0; i < orderDTO.size(); i++) {
            String senderCountry = orderDTO.get(i).getSenderCity();
            System.out.println(senderCountry);
            Result<List<LogisticsStoreDTOS>> byId = threeSelectFeign.findById(senderCountry);
            if(byId.getCode().equals(1007)){
                System.out.println("查询站点熔断");
                return Result.build(ConstantEnum.FaillBack).setResult("查询站点熔断");
            }
            LogisticsStoreDTOS result = byId.getResult().get(0);
            Long id = result.getId();
            orderDTO.get(i).setSiteName(id.toString());
        }

        //todo 修改订单的 预估金额
        BigDecimal bigDecimal2 = new BigDecimal(pri);
        for (int i = 0; i < orderDTO.size(); i++) {
            orderDTO.get(i).setOrderEstimatePrice(bigDecimal2);
            orderDTO.get(i).setSignReceipt(userDTO.getId().toString());
            if(!orderDTO.get(0).getTermsPayment().equals("1")){
                //1当面支付,2到付
                //生成支付宝流水号
                //如果是到付,直接生支付订单号,加set支付状态未支付
                //判断是否使用优惠券
                if(sid==null){
                    //没有使用优惠券
                }else {//使用优惠券
                    Coupon byId = couponService.getById(sid);
                    if(byId.getCouponType().equals("1")){
                        //满减
                        if(pri>=Integer.parseInt(byId.getCouponCondition())){
                            //可用
                            Integer aa = pri-(byId.getCouponSum().intValue());
                            String result = pay1(aa.toString()).getResult();
                            orderDTO.get(i).setSerialNumber(result);
                            orderDTO.get(i).setPaymentStatus(0);
                            //修改优惠券
                            int count = byId.getCouponCount()-1;
                            byId.setCouponCount(count);
                            couponService.updateById(byId);
                        }
                    }else if(byId.getCouponType().equals("2")){
                        //打折
                        double d = Integer.parseInt(byId.getCouponCondition());
                        Double b= pri*d;

                        Result pay = pay1(b.toString());
                        String result = (String)pay.getResult();
                        orderDTO.get(i).setSerialNumber(result);
                        orderDTO.get(i).setPaymentStatus(0);

                        int count = byId.getCouponCount()-1;
                        byId.setCouponCount(count);
                        couponService.updateById(byId);
                    }
                }
//优惠券结束
            }
        }
        //调用订单新增接口
        Result<List<Long>> listResult = orderServcieFeign.addOrder(orderDTO);
        if(listResult.getCode().equals(1007)){
            String message = listResult.getMessage();
            System.out.println(message);
            return Result.build(ConstantEnum.FaillBack).setResult("订单熔断");
        }
        return Result.build(ConstantEnum.SUCCESS).setResult(listResult);
    }



    //



    public Result<String> pay1(String price) throws AlipayApiException {
        //生成支付宝订单号
        String s = RandomStringUtils.randomNumeric(8);
        String s1 = tradeController.alipayTradePagePay(s, price, "1", "1");
        System.out.println(s1);
        //return "/trade/alipayTradePagePay?WIDout_trade_no="+s+"&WIDtotal_amount="+price+"&WIDsubject="+"订单名称"+"&WIDbody="+"订单描述";
        return Result.build(ConstantEnum.SUCCESS).setResult(s);
    }
    @ApiOperation(value = "支付")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "订单id", required = true, paramType = "query"),
    })
    @GetMapping("pay")
    public Result pay(@RequestParam Long id) throws AlipayApiException {
        //查price
        Result orderById = orderServcieFeign.findOrderById(id);
        OrderDTO result = (OrderDTO)orderById.getResult();
        if(result.getPaymentStatus()==2){
            return Result.build(ConstantEnum.PAYED);
        }
        BigDecimal orderEstimatePrice = result.getOrderEstimatePrice();
        String price = orderEstimatePrice.toString();
        //生成支付宝订单号
        String s = RandomStringUtils.randomNumeric(8);
        result.setAlyOrderNumber(s);
        orderServcieFeign.updateOrder(result);

        String s1 = tradeController.alipayTradePagePay(s, price, "1", "1");
        System.out.println(s1);
        //return "/trade/alipayTradePagePay?WIDout_trade_no="+s+"&WIDtotal_amount="+price+"&WIDsubject="+"订单名称"+"&WIDbody="+"订单描述";
        return Result.build(ConstantEnum.SUCCESS).setResult(s);
    }
    @ApiOperation(value = "生成运单")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "orderId", value = "订单id", required = true, paramType = "query")
    })
    @PostMapping("waybill")
    public Result waybill(@RequestParam Long orderId){
        //通过id查询订单
        //todo
        Result<OrderDTO> orderById = orderServcieFeign.findOrderById(orderId);
        if(orderById.getCode().equals(1007)){
            System.out.println(orderById.getMessage());
            return Result.build(ConstantEnum.FaillBack).setResult("查询熔断");
        }
        OrderDTO orderDTO = orderById.getResult();
        System.out.println(orderById.getMessage());
        System.out.println(orderDTO);
        if(orderDTO.getPaymentStatus()==1 && orderDTO.getPaymentStatus()==0){
            //未支付
            return Result.build(ConstantEnum.ERROR).setResult("未支付");
        }
        if(orderDTO.getTermsPayment()==1 && orderDTO.getPaymentStatus()==2){
            //当面支付，已支付，生成运单
            WaybillDTO waybillDTO = new WaybillDTO();
            waybillDTO.setOrderId(orderDTO.getId());//订单id
            waybillDTO.setCargoName(orderDTO.getCargoName());//货物名称
            waybillDTO.setCargoWeight(orderDTO.getCargoWeight());//货物重量
            waybillDTO.setCargoVolume(orderDTO.getCargoVolume());//货物体积
            waybillDTO.setCargoNumber(orderDTO.getCargoCount().longValue());//货物件数
            waybillDTO.setCargoInsurance(Integer.parseInt(orderDTO.getCargoInsurance()));//货物报价
            waybillDTO.setCollectionAgent("0");//退款
            waybillDTO.setWaybillReceipt(orderDTO.getSignReceipt());//签收单
            waybillDTO.setUpDoor(orderDTO.getDoorIsup());//是否上门(1t2f)
            waybillDTO.setConsigneeName(orderDTO.getConsigneeName());//收货人名称
            waybillDTO.setConsigneeProvince(orderDTO.getConsigneePhone());//收货人省
            waybillDTO.setConsigneePhone(orderDTO.getConsigneePhone());//收货人电话
            waybillDTO.setConsigneeCity(orderDTO.getConsigneeCity());//市
            waybillDTO.setConsigneeCountry(orderDTO.getConsigneeCountry());//县
            waybillDTO.setConsigneeAddress(orderDTO.getConsigneeAddress());//详细地址
            waybillDTO.setDeliveryMethod(orderDTO.getCargoMode());//送货方式
            waybillDTO.setLogisticsStatus(orderDTO.getOrderOverdue().toString());//订单状态
            //todo 调用路线接口
            System.out.println(orderDTO.getSenderAddress());
            System.out.println(orderDTO.getConsigneeAddress());
            Result<LineDTO> result1 = lineServcieFeign.selectByBoth(orderDTO.getSenderAddress(), orderDTO.getConsigneeAddress());
            if(result1.getCode().equals(1007)){
                System.out.println(result1.getMessage());
                return Result.build(ConstantEnum.FaillBack).setResult("路线熔断");
            }
            if(result1.getResult() == null){
                System.out.println(result1.getResult());
                return Result.build(ConstantEnum.ERROR).setResult("路线为null");

            }
            //test手动生成路线对象测试
             LineDTO lineDTO  = result1.getResult();
//            LineDTO lineDTO = new LineDTO();
//            lineDTO.setId(2L).setStatrAddress("北京").setEndAddress("天津").setSiteCount(2).setLineLength(141L).setLineTime(1L).setLineCity("[\"北京\",\"天津市\"]");
           // LineDTO result = result1.getResult();
            waybillDTO.setLineWaybill(lineDTO.getId());//路线表id*/
            waybillDTO.setWarehouseEntryTime(new Date());
            Long aLong = Long.valueOf(orderDTO.getSiteName());//当前运单所在那个站点
            waybillDTO.setCurrentSite(aLong);
            //当前运单所在那个站点,下一站站点id
            Result<LineLogisticsStoreDTO> next = lineServcieFeign.selectNextByLineId(lineDTO.getId(), aLong);
            if(next.getCode().equals(1007)){
                System.out.println("查询下一站站点熔断");
                return Result.build(ConstantEnum.FaillBack).setResult("查询下一站站点熔断");
            }
            waybillDTO.setNextLine(next.getResult().getLogisticsStoreId().toString());
            //创建明细表(自己写)
            Detailed detailed = new Detailed();
            detailed.setOrderId(orderDTO.getId());//订单id
            //detailed.setWaybillId()//运单id
            detailed.setCargoName(orderDTO.getCargoName());//物品名称
            detailed.setCargoWeight(orderDTO.getCargoWeight().longValue());//物品重量
            detailed.setCargoVolume(orderDTO.getCargoVolume());//物品体积
            detailed.setCargoNumber(orderDTO.getCargoCount().toString());//物品数量

            BigDecimal setCargoPrice = new BigDecimal(orderDTO.getCargoInsurancePrice().doubleValue());
            detailed.setCargoPrice(setCargoPrice);
            BigDecimal totalP = new BigDecimal(orderDTO.getCargoCount().intValue()*setCargoPrice.intValue());
            detailed.setTotalPrice(totalP);
            //新增明细表反回主键
            Long add = detailedService.add(detailed);
            // String s = JSONObject.toJSONString(add.getResult());
            //DetailedDTO o = JSONObject.parseObject(s,DetailedDTO.class);
            // Long detailedId = o.getDetailedId();
            //将明细id set到运单
            waybillDTO.setDetailedId(add);

            //todo
            //调用运单生成
            Result result2 = orderServcieFeign.addWaybill(waybillDTO);
            if(result2.getCode().equals(1007)){
                System.out.println(result2.getMessage());
                return Result.build(ConstantEnum.FaillBack).setResult("add熔断或者执行成功但是超时了,请查询");
            }else if (result2.getCode().equals(1004)){
                System.out.println(result2.getResult());
            }
        }
        return Result.build(ConstantEnum.SUCCESS);
    }
    @ApiOperation(value = "地址")
    @PostMapping("line")
    public Result sss(){
        Result<LineDTO> lineDTOResult = lineServcieFeign.selectByBoth("北京市", "郑州市");
        System.out.println(lineDTOResult.getResult());
        System.out.println(lineDTOResult.getMessage());
        return Result.build(ConstantEnum.SUCCESS);
    }
}
